﻿Imports System.Runtime.CompilerServices

Namespace Extensions

    ''' <summary>
    ''' Предоставляет методы, визуализирующие частичную разметку (сниппеты) в представлении.
    ''' </summary>
    ''' <remarks></remarks>
    Public Module SnippetHtmlHelper

        ''' <summary>
        ''' Возвращает фрагмент разметки, заключенного в контейнер элемента <c>aside</c>. Если фрагмент не имеет содержания, то возвращается пустая строка разметки.
        ''' </summary>
        ''' <param name="helper">Экземпляр вспомогательного метода HTML, который расширяется данным методом.</param>
        ''' <param name="name">Имя сниппета.</param>
        ''' <returns>Объект <see cref="MvcHtmlString" />, содержащий HTML-разметку для элемента <c>aside</c>.</returns>
        ''' <remarks></remarks>
        <Extension>
        Public Function Snippet(helper As HtmlHelper, name As String) As MvcHtmlString
            Return Snippet(helper, name, False, Nothing)
        End Function

        ''' <summary>
        ''' Возвращает фрагмент разметки, заключенного в контейнер элемента <c>aside</c>. Если фрагмент не имеет содержания, то возвращается пустая строка разметки.
        ''' </summary>
        ''' <param name="helper">Экземпляр вспомогательного метода HTML, который расширяется данным методом.</param>
        ''' <param name="name">Имя сниппета.</param>
        ''' <param name="useHeader">Разрешает добавить в контейнер сниппета элемент <c>header</c>, содержащий название.</param>
        ''' <returns>Объект <see cref="MvcHtmlString" />, содержащий HTML-разметку для элемента <c>aside</c>.</returns>
        ''' <remarks></remarks>
        <Extension>
        Public Function Snippet(helper As HtmlHelper, name As String, useHeader As Boolean) As MvcHtmlString
            Return Snippet(helper, name, useHeader, Nothing)
        End Function

        ''' <summary>
        ''' Возвращает фрагмент разметки, заключенного в контейнер элемента <c>aside</c>. Если фрагмент не имеет содержания, то возвращается пустая строка разметки.
        ''' </summary>
        ''' <param name="helper">Экземпляр вспомогательного метода HTML, который расширяется данным методом.</param>
        ''' <param name="name">Имя сниппета.</param>
        ''' <param name="htmlAttributes">Объект, который содержит HTML-аттрибуты для элемента.</param>
        ''' <returns>Объект <see cref="MvcHtmlString" />, содержащий HTML-разметку для элемента <c>aside</c>.</returns>
        ''' <remarks></remarks>
        <Extension>
        Public Function Snippet(helper As HtmlHelper, name As String, htmlAttributes As Object) As MvcHtmlString
            Return Snippet(helper, name, False, htmlAttributes)
        End Function

        ''' <summary>
        ''' Возвращает фрагмент разметки, заключенного в контейнер элемента <c>aside</c>. Если фрагмент не имеет содержания, то возвращается пустая строка разметки.
        ''' </summary>
        ''' <param name="helper">Экземпляр вспомогательного метода HTML, который расширяется данным методом.</param>
        ''' <param name="name">Имя сниппета.</param>
        ''' <param name="useHeader">Разрешает добавить в контейнер сниппета элемент <c>header</c>, содержащий название.</param>
        ''' <param name="htmlAttributes">Объект, который содержит HTML-аттрибуты для элемента.</param>
        ''' <returns>Объект <see cref="MvcHtmlString" />, содержащий HTML-разметку для элемента <c>aside</c>.</returns>
        ''' <remarks></remarks>
        <Extension>
        Public Function Snippet(helper As HtmlHelper, name As String, useHeader As Boolean, htmlAttributes As Object) As MvcHtmlString
            Dim model As Snippet

            Using db As New AzoxContext
                model = db.Snippets.SingleOrDefault(Function(m) m.Name.ToLower() = name.ToLower())

                If IsNothing(model) Then
                    model = db.Snippets.Add(New Snippet With {.Id = Guid.NewGuid, .Title = name, .Text = String.Empty, .Name = name})
                    db.SaveChanges()
                End If
            End Using

            If String.IsNullOrEmpty(model.Text) Then Return MvcHtmlString.Empty

            Dim asideTag As New TagBuilder("aside")
            With asideTag
                .GenerateId(name)
                .MergeAttributes(New RouteValueDictionary(htmlAttributes), True)
                If useHeader Then .InnerHtml = BuildHeader(model.Title).ToString(TagRenderMode.Normal)
                .InnerHtml += model.Text
            End With

            Return MvcHtmlString.Create(asideTag.ToString(TagRenderMode.Normal))
        End Function

        Private Function BuildHeader(title As String) As TagBuilder
            Dim headerTag As New TagBuilder("header")
            headerTag.SetInnerText(title)
            Return headerTag
        End Function
    End Module

End Namespace
